﻿using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Infrastructure;
using Microsoft.Practices.Prism.Logging;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Unity;
using Model;
using ViewsAndViewModels.Interfaces;
using ViewsAndViewModels.ViewModels;
using ViewsAndViewModels.Views;

namespace ViewsAndViewModels
{
    public class MainViewsController : IModule
    {
        private readonly IUnityContainer _container;
        private readonly IRegionManager _regionManager;
        private readonly ILoggerFacade _logger;
        private readonly PluginLoader _pluginLoader = new PluginLoader();
        public MainViewsController(IUnityContainer container, IRegionManager regionManager, ILoggerFacade logger)
        {
            _container = container;
            _regionManager = regionManager;
            _logger = logger;
        }
        public void Initialize()
        {
            LoadPlugins<IPasswordGenerator>();
            RegisterViewsAndServices();
            _regionManager.Regions[RegionNames.ContentRegion].Add(_container.Resolve<IMainContentViewModel>().View, ViewNames.MainViewName);
            _regionManager.Regions[RegionNames.ToolbarRegion].Add(_container.Resolve<IMainMenuViewModel>().View);
            _regionManager.Regions[RegionNames.ContentRegion].Add(_container.Resolve<IAboutViewModel>().View, ViewNames.AboutViewName);
            var startupView = _regionManager.Regions[RegionNames.ContentRegion].GetView(ViewNames.AboutViewName);
            if (startupView != null) _regionManager.Regions[RegionNames.ContentRegion].Activate(startupView);
            _regionManager.Regions[RegionNames.ContentRegion].Context = ViewNames.AboutViewName;
        }
        protected void RegisterViewsAndServices()
        {// note: register subscribers before publishers
            _container.RegisterType<IMainMenuView, MainMenuView>(); 
            _container.RegisterType<IMainMenuViewModel, MainMenuViewModel>();

            _container.RegisterType<IMainContentView, MainContentView>();
            _container.RegisterType<IMainContentViewModel, MainContentViewModel>();
            
            _container.RegisterType<IAboutView, AboutView>();
            _container.RegisterType<IAboutViewModel, AboutViewModel>();
        }
        protected void LoadPlugins<T>() where T:class 
        {
            var v = _pluginLoader.LoadPlugin<T>(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), _logger).ToList();
            if (v.Count == 1)
            {
                _container.RegisterInstance(typeof(T), v[0]);
            }
            else if (v.Count == 0)
            {
                throw new ApplicationException("Unable to locate plugin");
            }
            else
            {
                throw new ApplicationException("Multiple plugins found, resolution needed");
            }
        }
    }
}
